//*********************************************************
//
//    Copyright (c) Microsoft. All rights reserved.
//    This code is licensed under the Apache License, Version 2.0.
//    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
//    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
//    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
//    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************

namespace Microsoft.Research.eResearch.RuntimeServices.Tracking
{
    using System;
    using System.Workflow.ComponentModel;
    using System.Workflow.Runtime;
    using System.Workflow.Runtime.Tracking;
    using Microsoft.Research.eResearch.RuntimeServices.Blackboard;
    using Microsoft.Research.eResearch.RuntimeServices.Common;
    using Microsoft.Research.eResearch.RuntimeServices.Ontology;

    public class PropertyTrackingService : TrackingService
    {
        protected override void OnStarted()
        {
            base.OnStarted();

            // Make sure that other necessary services are present
            this.Runtime.GetBlackboardService();
            this.Runtime.GetOntologyMappingService();
        }

        protected override TrackingProfile GetProfile(Guid workflowInstanceId)
        {
            return GetDefaultProfile(workflowInstanceId);
        }

        protected override TrackingProfile GetProfile(Type workflowType, Version profileVersionId)
        {
            return GetDefaultProfile(WorkflowEnvironment.WorkflowInstanceId);
        }

        protected override TrackingChannel GetTrackingChannel(TrackingParameters parameters)
        {
            return new PropertyTrackingChannel(this.Runtime, parameters);
        }

        protected override bool TryGetProfile(Type workflowType, out TrackingProfile profile)
        {
            profile = GetDefaultProfile(WorkflowEnvironment.WorkflowInstanceId);
            return true;
        }

        protected override bool TryReloadProfile(Type workflowType, Guid workflowInstanceId, out TrackingProfile profile)
        {
            profile = GetDefaultProfile(workflowInstanceId);
            return true;
        }

        private TrackingProfile GetDefaultProfile(Guid workflowInstanceId)
        {
            TrackingProfile profile = new TrackingProfile();
            profile.Version = new Version(1, 0, 0, 0);

            // Use reflection to grab a reference to the PRIVATE root activity inside the WorkflowRuntime
            Activity rootActivity = WorkflowRuntimeHelper.GrabRootActivity(this.Runtime, workflowInstanceId);

            // Use reflection to create tracking data extracts for every property of every activity
            WorkflowRuntimeHelper.PopulateTrackingProfileExtracts(rootActivity, profile);

            WorkflowTrackPoint workflowTrackPoint = new WorkflowTrackPoint();
            workflowTrackPoint.MatchingLocation = new WorkflowTrackingLocation(WorkflowRuntimeHelper.AllTrackingWorkflowEvents);
            profile.WorkflowTrackPoints.Add(workflowTrackPoint);

            return profile;
        }
    }
}
